Sodium D2 Line¶
For atoms with hyperfine structure the nuclear spin I is no longer zero so there is coupling between the nuclear magnetic moment of the atom and the angular momentum of the electron cloud. This gives the atom hyperfine stucture.
Aims: * Model Sodium transition (see Farrell 1988 paper - https://doi.org/10.1103/PhysRevA.37.4240) * Compare the Sodium with the paper by Farrell. Do these match exactly?
[1]:
%run "base-LASED/LASED/laser_atom_system.py"
%run "base-LASED/LASED/time_evolution.py"
%run "base-LASED/LASED/generate_sub_states.py"
import plotly.graph_objects as go
import time
Including Hyperfine Structure¶
Hyperfine splitting of atomic energy levels is from the coupling of the nuclear-spin (iso-spin) I with the sum of the state’s spin S and orbiatl angular momentum L. This results in a total angular momentum F:
If an atom has non-zero nuclear spin then the projection of the electron’s angular momentum is \(m_F\). This results in a different coupling between states (different dipole operator matrix element which couple two states together). The coupling between ground state |g> with angular momentum |F’, m\(_F\)> and excited state |e> with angular momentum |F, m\(_F\)> is [Farrell 1995]:
where q is the polarisation of the laser radiation: -1 if \(\sigma+\), +1 if \(\sigma-\), and 0 if \(\pi\).
Sodium D\(_2\) Line¶
In Farrell’s 1988 paper the orange Sodium D\(_2\) line was modelled, specifically the 3\(^2\)S\(_{1/2}\) (F’ = 2) to the 3\(^2\)P\(_{3/2}\) (F = 3,2,1) transition. See Farrell’s paper for the atomic level diagram and information about the hyperfine structure modelling. Farrell also compares the QED approach to the semi-classical (SC) model and shows that the SC model agrees with the QED model at low intensities but the approaches diverge at higher intensities.
The data for the Sodium D line can be found here.
[2]:
# 3^2S_{1/2} -> 3^2P_{3/2}
wavelength_na = 589.159e-9 # Wavelength in m
w_e = angularFreq(wavelength_na)
tau_na = 16.24 # in ns
I_Na = 3/2 # Isospin for sodium
# Energy Splittings
w1 = 1.77*2*PI # Splitting of 3^2S_{1/2}(F = 1) - (F = 2) in Grad/s
w2 = 0.0158*2*PI # Splitting between 3^2P_{3/2} (F = 0) and F = 1 in Grad/s
w3 = 0.0355*2*PI # Splitting between 3^2P_{3/2} (F = 1) and F = 2 in Grad/s
w4 = 0.0595*2*PI # Splitting between 3^2P_{3/2} (F = 2) and F = 3 in Grad/s
# Detunings
w_Fp1 = -1*w1
w_F0 = w_e-(w4+w3+w2)
w_F1 = w_e-(w4+w3)
w_F2 = w_e-w4
w_F3 = w_e
# Model
# # 3^2S_{1/2} F' = 1
# s1 = State(label = 1, w = 0, m = -1, L = 0, S = 1/2, I = I_Na, F = 1)
Fp1 = generateSubStates(label_from = 1, w = w_Fp1, L = 0, S = 1/2, I = I_Na, F = 1)
# # 3^2S_{1/2} F' = 2
Fp2 = generateSubStates(label_from = 4, w = 0, L = 0, S = 1/2, I = I_Na, F = 2)
# # 3^2P_{3/2} F = 0
# s9 = State(label = 9, w = w_F0, m = 0, L = 1, S = 1/2, I = I_Na, F = 0)
F0 = generateSubStates(label_from = 9, w = w_F0, L = 1, S = 1/2, I = I_Na, F = 0)
# # # 3^2P_{3/2} F = 1
F1 = generateSubStates(label_from = 10, w = w_F1, L = 1, S = 1/2, I = I_Na, F = 1)
# s10 = State(label = 10, w = w_F1, m = -1, L = 1, S = 1/2, I = I_Na, F = 1)
# # # 3^2P_{3/2} F = 2
F2 = generateSubStates(label_from = 13, w = w_F2, L = 1, S = 1/2, I = I_Na, F = 2)
# s13 = State(label = 13, w = w_F2, m = -2, L = 1, S = 1/2, I = I_Na, F = 2)
# # 3^2P_{3/2} F = 3
F3 = generateSubStates(label_from = 18, w = w_F3, L = 1, S = 1/2, I = I_Na, F = 3)
G_na = Fp1 + Fp2
E_na = F0 + F1 + F2 + F3
# Laser parameters
intensity_na = 85.6 # mW/mm^-2
Q_na = [0]
Q_decay = [1, 0, -1]
# Simulation parameters
start_time = 0
stop_time = 500 # in ns
time_steps = 501
time_na = np.linspace(start_time, stop_time, time_steps)
rabi = te.halfRabiFreq(intensity_na, tau_na, wavelength_na)
print(f"rabi = {rabi/np.sqrt(intensity_na)} Grad/s (mW/mm^-2)^-1/2")
for e in E_na:
for g in G_na:
for q in Q_na:
c_eg = te.coupling(e, g, q)
if(c_eg):
print( f"C_{e.label},{g.label}^{q} = {c_eg}, rabi = {rabi*c_eg*1000/(np.sqrt(intensity_na)*PI)} Mhz/(mW/mm^-2)")
rabi = 0.0869877402901387 Grad/s (mW/mm^-2)^-1/2
C_9,1^1 = 0.235702260395516*sqrt(6), rabi = 6.52637349073739*sqrt(6) Mhz/(mW/mm^-2)
C_9,2^0 = 0.235702260395516*sqrt(6), rabi = 6.52637349073739*sqrt(6) Mhz/(mW/mm^-2)
C_9,3^-1 = -0.235702260395516*sqrt(6), rabi = -6.52637349073739*sqrt(6) Mhz/(mW/mm^-2)
C_10,1^0 = -0.204124145231931*sqrt(10), rabi = -5.65200523756391*sqrt(10) Mhz/(mW/mm^-2)
C_10,2^-1 = 0.204124145231931*sqrt(10), rabi = 5.65200523756391*sqrt(10) Mhz/(mW/mm^-2)
C_10,4^1 = 0.316227766016838, rabi = 8.75604886310485 Mhz/(mW/mm^-2)
C_10,5^0 = 0.158113883008419*sqrt(2), rabi = 4.37802443155242*sqrt(2) Mhz/(mW/mm^-2)
C_10,6^-1 = -0.052704627669473*sqrt(6), rabi = -1.45934147718414*sqrt(6) Mhz/(mW/mm^-2)
C_11,1^1 = 0.204124145231931*sqrt(10), rabi = 5.65200523756391*sqrt(10) Mhz/(mW/mm^-2)
C_11,3^-1 = 0.204124145231931*sqrt(10), rabi = 5.65200523756391*sqrt(10) Mhz/(mW/mm^-2)
C_11,5^1 = 0.158113883008419*sqrt(2), rabi = 4.37802443155242*sqrt(2) Mhz/(mW/mm^-2)
C_11,6^0 = 0.105409255338946*sqrt(6), rabi = 2.91868295436828*sqrt(6) Mhz/(mW/mm^-2)
C_11,7^-1 = -0.158113883008419*sqrt(2), rabi = -4.37802443155242*sqrt(2) Mhz/(mW/mm^-2)
C_12,2^1 = 0.204124145231931*sqrt(10), rabi = 5.65200523756391*sqrt(10) Mhz/(mW/mm^-2)
C_12,3^0 = 0.204124145231931*sqrt(10), rabi = 5.65200523756391*sqrt(10) Mhz/(mW/mm^-2)
C_12,6^1 = 0.052704627669473*sqrt(6), rabi = 1.45934147718414*sqrt(6) Mhz/(mW/mm^-2)
C_12,7^0 = 0.158113883008419*sqrt(2), rabi = 4.37802443155242*sqrt(2) Mhz/(mW/mm^-2)
C_12,8^-1 = -0.316227766016838, rabi = -8.75604886310485 Mhz/(mW/mm^-2)
C_13,1^-1 = -0.316227766016838*sqrt(5), rabi = -8.75604886310485*sqrt(5) Mhz/(mW/mm^-2)
C_13,4^0 = -0.408248290463863*sqrt(2), rabi = -11.3040104751278*sqrt(2) Mhz/(mW/mm^-2)
C_13,5^-1 = 0.408248290463863, rabi = 11.3040104751278 Mhz/(mW/mm^-2)
C_14,1^0 = -0.158113883008419*sqrt(10), rabi = -4.37802443155242*sqrt(10) Mhz/(mW/mm^-2)
C_14,2^-1 = -0.158113883008419*sqrt(10), rabi = -4.37802443155242*sqrt(10) Mhz/(mW/mm^-2)
C_14,4^1 = 0.408248290463863, rabi = 11.3040104751278 Mhz/(mW/mm^-2)
C_14,5^0 = -0.204124145231932*sqrt(2), rabi = -5.65200523756391*sqrt(2) Mhz/(mW/mm^-2)
C_14,6^-1 = 0.204124145231932*sqrt(6), rabi = 5.65200523756391*sqrt(6) Mhz/(mW/mm^-2)
C_15,1^1 = 0.052704627669473*sqrt(30), rabi = 1.45934147718414*sqrt(30) Mhz/(mW/mm^-2)
C_15,2^0 = -0.105409255338946*sqrt(30), rabi = -2.91868295436828*sqrt(30) Mhz/(mW/mm^-2)
C_15,3^-1 = -0.052704627669473*sqrt(30), rabi = -1.45934147718414*sqrt(30) Mhz/(mW/mm^-2)
C_15,5^1 = 0.204124145231932*sqrt(6), rabi = 5.65200523756391*sqrt(6) Mhz/(mW/mm^-2)
C_15,7^-1 = 0.204124145231932*sqrt(6), rabi = 5.65200523756391*sqrt(6) Mhz/(mW/mm^-2)
C_16,2^1 = 0.158113883008419*sqrt(10), rabi = 4.37802443155242*sqrt(10) Mhz/(mW/mm^-2)
C_16,3^0 = -0.158113883008419*sqrt(10), rabi = -4.37802443155242*sqrt(10) Mhz/(mW/mm^-2)
C_16,6^1 = 0.204124145231932*sqrt(6), rabi = 5.65200523756391*sqrt(6) Mhz/(mW/mm^-2)
C_16,7^0 = 0.204124145231932*sqrt(2), rabi = 5.65200523756391*sqrt(2) Mhz/(mW/mm^-2)
C_16,8^-1 = 0.408248290463863, rabi = 11.3040104751278 Mhz/(mW/mm^-2)
C_17,3^1 = 0.316227766016838*sqrt(5), rabi = 8.75604886310485*sqrt(5) Mhz/(mW/mm^-2)
C_17,7^1 = 0.408248290463863, rabi = 11.3040104751278 Mhz/(mW/mm^-2)
C_17,8^0 = 0.408248290463863*sqrt(2), rabi = 11.3040104751278*sqrt(2) Mhz/(mW/mm^-2)
C_18,4^-1 = -0.0690065559342354*sqrt(210), rabi = -1.91072650971*sqrt(210) Mhz/(mW/mm^-2)
C_19,4^0 = -0.0690065559342354*sqrt(70), rabi = -1.91072650971*sqrt(70) Mhz/(mW/mm^-2)
C_19,5^-1 = -0.138013111868471*sqrt(35), rabi = -3.82145301942*sqrt(35) Mhz/(mW/mm^-2)
C_20,4^1 = 0.0690065559342354*sqrt(14), rabi = 1.91072650971*sqrt(14) Mhz/(mW/mm^-2)
C_20,5^0 = -0.276026223736942*sqrt(7), rabi = -7.64290603884*sqrt(7) Mhz/(mW/mm^-2)
C_20,6^-1 = -0.138013111868471*sqrt(21), rabi = -3.82145301942*sqrt(21) Mhz/(mW/mm^-2)
C_21,5^1 = 0.0690065559342354*sqrt(42), rabi = 1.91072650971*sqrt(42) Mhz/(mW/mm^-2)
C_21,6^0 = -0.207019667802706*sqrt(14), rabi = -5.73217952913*sqrt(14) Mhz/(mW/mm^-2)
C_21,7^-1 = -0.0690065559342354*sqrt(42), rabi = -1.91072650971*sqrt(42) Mhz/(mW/mm^-2)
C_22,6^1 = 0.138013111868471*sqrt(21), rabi = 3.82145301942*sqrt(21) Mhz/(mW/mm^-2)
C_22,7^0 = -0.276026223736942*sqrt(7), rabi = -7.64290603884*sqrt(7) Mhz/(mW/mm^-2)
C_22,8^-1 = -0.0690065559342354*sqrt(14), rabi = -1.91072650971*sqrt(14) Mhz/(mW/mm^-2)
C_23,7^1 = 0.138013111868471*sqrt(35), rabi = 3.82145301942*sqrt(35) Mhz/(mW/mm^-2)
C_23,8^0 = -0.0690065559342354*sqrt(70), rabi = -1.91072650971*sqrt(70) Mhz/(mW/mm^-2)
C_24,8^1 = 0.0690065559342354*sqrt(210), rabi = 1.91072650971*sqrt(210) Mhz/(mW/mm^-2)
[4]:
sodium_system = LaserAtomSystem(E_na, G_na, tau_na, Q_na, wavelength_na,
laser_intensity = intensity_na)
tic = time.perf_counter()
sodium_system.timeEvolution(time_na, pretty_print_eq = True)
toc = time.perf_counter()
print(f"The code finished in {toc-tic:0.4f} seconds")
Populating ground states equally as the initial condition.
The code finished in 1212.1779 seconds
[5]:
las_sys = sodium_system
rho_to_plot = [ [abs(rho) for rho in las_sys.Rho_t(s, s)] for s in F0]
fig_na = go.Figure()
for i, rho_ee in enumerate(rho_to_plot):
fig_na.add_trace(go.Scatter(x = time_na,
y = rho_ee,
name = f"m_F = {F0[i].m}",
mode = 'lines'))
fig_na.update_layout(title = "Sodium F = 0",
xaxis_title = "Time (ns)",
yaxis_title = "Population",
font = dict(
size = 11))
fig_na.write_image("NaF=0I=856.pdf")
fig_na.show()
[6]:
las_sys = sodium_system
rho_to_plot = [ [abs(rho) for rho in las_sys.Rho_t(s, s)] for s in F1]
fig_na = go.Figure()
for i, rho_ee in enumerate(rho_to_plot):
fig_na.add_trace(go.Scatter(x = time_na,
y = rho_ee,
name = f"m_F = {F1[i].m}",
mode = 'lines'))
fig_na.update_layout(title = "Sodium F = 1",
xaxis_title = "Time (ns)",
yaxis_title = "Population",
font = dict(
size = 11))
fig_na.write_image(f"NaF=1I=856.pdf")
fig_na.show()
[7]:
las_sys = sodium_system
rho_to_plot = [ [abs(rho) for rho in las_sys.Rho_t(s, s)] for s in F2]
fig_na = go.Figure()
for i, rho_ee in enumerate(rho_to_plot):
fig_na.add_trace(go.Scatter(x = time_na,
y = rho_ee,
name = f"m_F = {F2[i].m}",
mode = 'lines'))
fig_na.update_layout(title = "Sodium F = 2",
xaxis_title = "Time (ns)",
yaxis_title = "Population",
font = dict(
size = 11))
fig_na.write_image("NaF=2I=856.pdf")
fig_na.show()
[8]:
las_sys = sodium_system
rho_to_plot = [ [abs(rho) for rho in las_sys.Rho_t(s, s)] for s in F3]
fig_na = go.Figure()
for i, rho_ee in enumerate(rho_to_plot):
fig_na.add_trace(go.Scatter(x = time_na,
y = rho_ee,
name = f"m_F = {F3[i].m}",
mode = 'lines'))
fig_na.update_layout(title = "Sodium F = 3",
xaxis_title = "Time (ns)",
yaxis_title = "Population",
font = dict(
size = 11))
fig_na.write_image("NaF=3I=856.pdf")
fig_na.show()
[9]:
fig_na_lower = go.Figure()
rho_to_plot = [ [abs(rho) for rho in las_sys.Rho_t(s, s)] for s in Fp1]
for i, rho_gg in enumerate(rho_to_plot):
fig_na_lower.add_trace(go.Scatter(x = time_na,
y = rho_gg,
name = f"m_F = {Fp1[i].m}",
mode = 'lines'))
fig_na_lower.update_layout(title = "Sodium F' = 1",
xaxis_title = "Time (ns)",
yaxis_title = "Population",
font = dict(
size = 11))
fig_na.write_image("NaFp=1I=856.pdf")
fig_na_lower.show()
[10]:
fig_na_lower = go.Figure()
rho_to_plot = [ [abs(rho) for rho in las_sys.Rho_t(s, s)] for s in Fp2]
for i, rho_gg in enumerate(rho_to_plot):
fig_na_lower.add_trace(go.Scatter(x = time_na,
y = rho_gg,
name = f"m_F = {Fp2[i].m}",
mode = 'lines'))
fig_na_lower.update_layout(title = "Sodium F' = 2",
xaxis_title = "Time (ns)",
yaxis_title = "Population",
font = dict(
size = 11))
fig_na.write_image("NaFp=2I=856.pdf")
fig_na_lower.show()
[34]:
# Make subplots
from plotly.subplots import make_subplots
fig = make_subplots(rows = 3, cols = 2, shared_xaxes = True,
subplot_titles = ["F = 0", "F = 1"])
# F = 0
rho_to_plot = [ [abs(rho) for rho in las_sys.Rho_t(s, s)] for s in F0]
for i, rho_ee in enumerate(rho_to_plot):
fig.add_trace(go.Scatter(x = time_na,
y = rho_ee,
name = f"m_F = {F0[i].m}",
mode = 'lines'),
row = 1, col = 1)
# F = 1
rho_to_plot = [ [abs(rho) for rho in las_sys.Rho_t(s, s)] for s in F1]
for i, rho_ee in enumerate(rho_to_plot):
fig.add_trace(go.Scatter(x = time_na,
y = rho_ee,
name = f"m_F = {F1[i].m}",
mode = 'lines'),
row = 1, col = 2)
fig['layout'].update(
annotations=[
dict(
x=97, y=498e-6, # annotation point
xref='x1',
yref='y1',
text='m<sub>F</sub>=0',
showarrow=True,
),
# dict(
# ...
# # if have multiple annotations
# )
])
fig.update_layout(title = "Level Populations of Sodium D-line after Laser Excitation",
xaxis_title = "Time (ns)",
yaxis_title = "Population",
font = dict(
size = 11))
# fig.add_annotation(x = 97, y = 498e-6, text = "m_F = 0", showarrow = True)
# fig.add_annotation(x2 = 12, y2 = 0.04, text = "m_F = 0", showarrow = True)
fig.show()